package com.itsu.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itsu.app.config.HuanXinConfig;
import com.itsu.app.exception.MyException;
import com.itsu.app.interceptor.UserThreadLocal;
import com.itsu.commons.utils.VoUtil;
import com.itsu.interfaces.entity.Question;
import com.itsu.interfaces.entity.RecommendUser;
import com.itsu.interfaces.entity.UserInfoEntity;
import com.itsu.interfaces.entity.UserLike;
import com.itsu.interfaces.service.RecommendUserService;
import com.itsu.interfaces.service.UserInfoService;
import com.itsu.interfaces.service.UserLikeService;
import com.itsu.interfaces.service.UserLocationService;
import com.itsu.pojo.constants.Constants;
import com.itsu.pojo.dto.RecommendationDTO;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import com.itsu.pojo.vo.PageResult;
import com.itsu.pojo.vo.TodayBest;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AppTanhuaService {

    @Reference
    RecommendUserService recommendUserService;

//    @Reference
//    UserLocationService updateUserLocation;

    @Reference
    UserLikeService userLikeService;

    @Autowired
    AppUserInfoService appUserInfoService;

    @Autowired
    AppQuestionService appQuestionService;

    @Autowired
    RequestService requestService;

    @Autowired
    HuanXinConfig huanXinConfig;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    public TodayBest todayBest() {
        //获取token中的用户id
        Long uid = UserThreadLocal.getUid();
        //查询配对分最高的用户
        RecommendUser recommendUser = recommendUserService.queryWithMaxScore(uid);
        if (ObjectUtil.isEmpty(recommendUser)) {
            throw new MyException(new ErrorResult(ResultCode.TODAY_BEST_NULL));
        }


        UserInfoEntity userInfoEntity = appUserInfoService.findUserByUid(uid);

        //生成VO对象
        return VoUtil.init(userInfoEntity, recommendUser);
//        TodayBest todayBest = TodayBest.builder()
//                .id(uid)
//                .avatar(userInfoEntity.getLogo())
//                .age(userInfoEntity.getAge())
//                .fateValue(recommendUser.getScore().longValue())
//                .gender(userInfoEntity.getSex() == 1 ? "man":"woman")
//                .nickname(userInfoEntity.getNickName())
//                .tags(userInfoEntity.getTags().length() > 0 ? userInfoEntity.getTags().split(",") : null)
//                .build();

    }


    public PageResult recommendation(RecommendationDTO recommendationDTO) {
        //获取token中的用户id
        Long uid = UserThreadLocal.getUid();
        //获取用户推荐的用户的uid集合
        List<RecommendUser> RecommendUserList = recommendUserService.getRecommendsByUid(uid);
        //判断用户uid集合
        if (CollUtil.isEmpty(RecommendUserList)) {
            throw new MyException(new ErrorResult(ResultCode.RECOMMENDATION_NULL));
        }
        //获取集合中的uid集合
        List<Long> userIds = CollUtil.getFieldValues(RecommendUserList, "userId", Long.class);
        //获取推荐人个人信息的分页对象
        Page<UserInfoEntity> page = appUserInfoService.findUserListOfRecommendation(userIds, recommendationDTO);

        //获取用户信息对象集合
        List<UserInfoEntity> records = page.getRecords();

        List<TodayBest> volist = new ArrayList<>();

        Map<Object, UserInfoEntity> userList = new HashMap<>();
        if (CollUtil.isNotEmpty(records)) {
            userList = CollUtil.fieldValueMap(records, "userId");
        }
        //生成推荐者对象集合
        for (RecommendUser user : RecommendUserList) {
            UserInfoEntity userInfoEntity = userList.get(user.getUserId());
            if (ObjectUtil.isNotEmpty(userInfoEntity)) {
                volist.add(VoUtil.init(userInfoEntity, user));
            }
        }

        return new PageResult(page.getTotal(), Convert.toInt(page.getSize()) , page.getPages(), Convert.toInt(page.getCurrent()), volist);
    }

    public TodayBest queryUserInfo(Long userId) {
        RecommendUser recommendUser = recommendUserService.queryScore(userId, UserThreadLocal.getUid());

        UserInfoEntity entity = appUserInfoService.findUserByUid(userId);

        return VoUtil.init(entity, recommendUser);
    }


    public Question queryQuestion(Integer userId) {
        return appQuestionService.findQuestion(userId);
    }

    public void replyQuestion(Integer userId, String reply) {
        /*
        {"userId":1,"huanXinId":"HX_1","nickname":"黑马小妹",
                "strangerQuestion":"你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
                "reply":"我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"}

       */

        UserInfoEntity entity = appUserInfoService.findUserByUid(Convert.toLong(userId));

        Question question = appQuestionService.findQuestion(userId);


        Map<String, String> map = new HashMap<>();
        map.put("userId", userId.toString());
        map.put("huanXinId", "HX_" + userId);
        map.put("nickname", entity.getNickName());
        map.put("strangerQuestion", question.getTxt());
        map.put("reply", reply);


        HttpResponse response = requestService.execute(huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/messages"
                , JSONUtil.createObj()
                        .set("target_type", "users")
                        .set("target", JSONUtil.createArray().put("HX_" + userId))
                        .set("msg", JSONUtil.createObj().set("type", "txt")
                                .set("msg", JSONUtil.toJsonStr(map)))
                        .toString()
                , Method.POST);

        if (!response.isOk()) {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }
    }

    public List<TodayBest> queryCardUser() {
        Long uid = UserThreadLocal.getUid();
        List<RecommendUser> RecommendUserList = recommendUserService.getRecommendsByUid(uid);
        if (CollUtil.isEmpty(RecommendUserList)) {
            throw new MyException(new ErrorResult(ResultCode.RECOMMENDATION_NULL));
        }

        List<Long> userIds = CollUtil.getFieldValues(RecommendUserList, "userId", Long.class);

        List<UserInfoEntity> infoEntityList = appUserInfoService.findUserByUids(userIds);

        List<TodayBest> vo = new ArrayList<>();
        for (UserInfoEntity userInfo : infoEntityList) {
            TodayBest todayBest = new TodayBest();
            todayBest.setId(userInfo.getUserId());
            todayBest.setAvatar(userInfo.getLogo());
            todayBest.setNickname(userInfo.getNickName());
            todayBest.setGender(userInfo.getSex() == 1 ? "woman" : "man");
            todayBest.setAge(userInfo.getAge());
            if (userInfo.getTags() != null) {
                todayBest.setTags(userInfo.getTags().split(","));
            }

            vo.add(todayBest);
        }
        return vo;
    }

    public void likeCardUser(Long userId) {
        UserLike userLike = new UserLike();
        userLike.setUserId(UserThreadLocal.getUid());
        userLike.setLikeUserId(userId);
        userLike.setCreated(System.currentTimeMillis());
        userLikeService.saveUserLike(userLike);

        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserThreadLocal.getUid(), userId.toString());
    }

    public void unLikeCardUser(Long userId) {
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserThreadLocal.getUid(), userId.toString());
    }

    // 上传/更新用户位置信息
//    public void updateLocation(Double longitude, Double latitude, String address) {
//        updateUserLocation.updateUserLocation(UserThreadLocal.getUid()
//                , longitude, latitude, address);
//    }
}
